# frozen_string_literal: true

SCHEMA_NOT_UPDATED_MESSAGE_SHORT = "New %<migrations>s added but %<schema>s wasn't updated"

SCHEMA_NOT_UPDATED_MESSAGE_FULL = <<~MSG
**#{SCHEMA_NOT_UPDATED_MESSAGE_SHORT}**

Usually, when adding new %<migrations>s, %<schema>s should be
updated too (unless the migration isn't changing the DB schema
and isn't the most recent one).
MSG

DB_MESSAGE = <<~MSG
This merge request requires a database review. To make sure these
changes are reviewed, take the following steps:

1. Ensure the merge request has ~database and ~"database::review pending" labels.
   If the merge request modifies database files, Danger will do this for you.
1. Prepare your MR for database review according to the
   [docs](https://docs.gitlab.com/ee/development/database_review.html#how-to-prepare-the-merge-request-for-a-database-review).
1. Assign and mention the database reviewer suggested by Reviewer Roulette.
MSG

DB_FILES_MESSAGE = <<~MSG
The following files require a review from the Database team:
MSG

DB_REMOVE_MESSAGE = <<~MSG
If you no longer require a database review, you can remove this suggestion
by removing the ~database label and re-running the [`danger-review` job](#{ENV['CI_JOB_URL']}).
MSG

DB_MIGRATION_TESTING_REQUIRED_MESSAGE = <<~MSG
The [database migration pipeline](https://docs.gitlab.com/ee/development/database/database_migration_pipeline.html)
must be triggered by the job `db:gitlabcom-database-testing` must be run before requesting
~database review. This job takes ~30m and will post the results to a comment on the merge
request. Please run and review any results before passing to a reviewer.
MSG

DB_OLD_MIGRATIONS_MESSAGE = <<~MSG
  ⌛ **Migration Timestamp Out of Date**
  The following migrations have timestamps that are over three weeks old:

  %<old_migrations>s

  Please double check the timestamps and update them if possible. [Why does this matter?](https://docs.gitlab.com/ee/development/migration_style_guide.html#migration-timestamp-age)
MSG

DATABASE_APPROVED_LABEL = 'database::approved'
DATABASE_TESTING_RUN_LABEL = 'database-testing-automation'
COMMUNITY_CONTRIBUTION_LABEL = 'Community contribution'

non_geo_db_schema_updated = !git.modified_files.grep(%r{\Adb/structure\.sql}).empty?
geo_db_schema_updated = !git.modified_files.grep(%r{\Aee/db/geo/structure\.sql}).empty?

non_geo_migration_created = !git.added_files.grep(%r{\A(db/(post_)?migrate)/}).empty?
geo_migration_created = !git.added_files.grep(%r{\Aee/db/geo/(post_)?migrate/}).empty?

format_str = helper.ci? ? SCHEMA_NOT_UPDATED_MESSAGE_FULL : SCHEMA_NOT_UPDATED_MESSAGE_SHORT

return if stable_branch.valid_stable_branch?

if non_geo_migration_created && !non_geo_db_schema_updated
  warn format(format_str, migrations: 'migrations', schema: helper.html_link("db/structure.sql"))
end

if geo_migration_created && !geo_db_schema_updated
  warn format(format_str, migrations: 'Geo migrations', schema: helper.html_link("ee/db/geo/structure.sql"))
end

return unless helper.ci?
return if helper.mr_labels.include?(DATABASE_APPROVED_LABEL)

migration_testing_has_run = helper.mr_labels.include?(DATABASE_TESTING_RUN_LABEL)
community_contribution = helper.mr_labels.include?(COMMUNITY_CONTRIBUTION_LABEL)
if non_geo_migration_created && !migration_testing_has_run && !community_contribution
  fail DB_MIGRATION_TESTING_REQUIRED_MESSAGE # rubocop:disable Style/SignalException
end

if helper.mr_labels.include?('database') || database.changes.any?
  message 'This merge request adds or changes files that require a ' \
    'review from the [Database team](https://gitlab.com/groups/gl-database/-/group_members).'

  markdown(DB_MESSAGE)

  db_paths_to_review = database.changed_database_paths

  if db_paths_to_review.any?
    markdown(DB_FILES_MESSAGE + helper.markdown_list(db_paths_to_review.to_set))
  else
    markdown(DB_REMOVE_MESSAGE)
  end

  unless helper.has_scoped_label_with_scope?("database")
    helper.labels_to_add << 'database::review pending'
  end
end

cutoff = Date.today - 21 # Three weeks ago

old_migrations = database.find_migration_files_before(git.added_files, cutoff)

if old_migrations.any?
  warn format(DB_OLD_MIGRATIONS_MESSAGE, old_migrations: old_migrations.map { |m| "* #{m}" }.join("\n"))
end
